/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package com.wzhq.commTencent;

import com.jfinal.plugin.activerecord.Db;
import com.jfinal.plugin.activerecord.Record;
import static com.wzhq.commTencent.PostTencent.POSTDICOM;
import com.wzhq.util.base64;
import com.wzhq.pacsai.DicomUtil;
import com.wzhq.util.JsfUtil;
import java.io.IOException;
import java.nio.charset.Charset;
import java.sql.Timestamp;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.logging.Level;
import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.HttpsURLConnection;
import net.sf.json.JSONArray;
import net.sf.json.JSONException;
import net.sf.json.JSONObject;
import org.apache.http.Header;
import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.conn.scheme.Scheme;
import org.apache.http.conn.scheme.SchemeRegistry;
import org.apache.http.conn.ssl.SSLSocketFactory;
import org.apache.http.conn.ssl.X509HostnameVerifier;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.impl.conn.SingleClientConnManager;
import org.apache.http.params.CoreConnectionPNames;
import org.apache.http.util.EntityUtils;
import org.dcm4che3.data.Tag;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 *
 * @author GG
 */
public class PostDcm implements Runnable {

    private static final Logger LogUtil = LoggerFactory.getLogger(PostDcm.class);
    private static final int ErrorCodeHelperIAS_SUCCESS = 9999;
    private String jobName;

    PostDcm() {
    }

    PostDcm(String jobName) {
        this.jobName = jobName;
    }

    //防止线程读同一个病人锁  ,0开，其它值锁，1影像下载锁，2图像上传锁，3取报告锁
    public static boolean lockUsingFlag(String StudyInstanceUID, int lock) {
        Record syncAIStatusLock = Db.findById("syncAIStatus", "StudyInstanceUID", StudyInstanceUID).set("UsingFlag", lock);
        Db.update("syncAIStatus", "StudyInstanceUID", syncAIStatusLock);
        return false;
    }

    //向服务器POST DICOM 数据
    public String postJsonDcm(String postUrl, String interfaces) {
        boolean isSuccess = false;
        JSONObject postImages = new JSONObject();//new一个JSONObject对象，命名为postImages
        JSONArray jsonArray = new JSONArray();
        Date day = new Date();
        SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        Object nullObj = null; //解决put中因二义性引起的编译错误

        // 在同步表中查找符合上传条件的图像，已PACS下载 且 未锁  且 没有上传或上传出错
        List<Record> syncAIStatus = Db.find("select * from SyncAiStatus where SyncFlag=1 and UsingFlag=0 "
                + "and (SyncAiFinshFlag=0 or(SyncAiFinshFlag=2 and SyncAiCounts<?)) ORDER BY SyncTime LIMIT 1", PostTencent.MAXREOPER);
        if ((syncAIStatus == null) || (syncAIStatus.isEmpty())) {
            //无新图像
            return "无新图像可供上传！";
        }
        String studyId = syncAIStatus.get(0).getStr("StudyInstanceUID");
        String StudyInstanceUID = studyId;
        lockUsingFlag(StudyInstanceUID, 2);

        String studyName = syncAIStatus.get(0).getStr("StudyName");
        Timestamp studyDate = syncAIStatus.get(0).getTimestamp("StudyDate");
        int studyType = syncAIStatus.get(0).getInt("StudyType");
        String patientName = syncAIStatus.get(0).getStr("PatientName");
        String patientId = syncAIStatus.get(0).getStr("PatientId");
        String seriesNo = StudyInstanceUID;

        try {
            postImages.put("studyId", studyId);
            postImages.put("studyName", studyName);//"MG");
            // postImages.put("studyDate", studyDate);//dateToStamp("2018-02-13 11:11:11", "yyyy-MM-dd HH:mm:ss"));
            postImages.put("studyType", studyType);
            //postImages.put("patientName", patientName);
            //postImages.put("patientId", patientId);
            postImages.put("seriesNo", seriesNo); //"1.2.840.113681.2230565556.954.3591564731.78.1");
            //postImages.put("uploadDone", uploadDone);//"1");
            //postImages.put("patientGender", "1");
            //postImages.put("patientBirthday", "2017-08-22");

            //向JSON中添加图像,JsonFlag标记表示本图像已加入JSON串中 0
            List<Record> MainImages = Db.find("SELECT SeriesInstanceUID,SOPInstanceUID,FilePath,FileName,FileSize "
                    + "FROM MainImages WHERE StudyInstanceUID=? AND (UploadFlag=0 OR (UploadFlag=2 and UploadCounts<?)) ",
                    StudyInstanceUID, PostTencent.MAXREOPER);
            if ((MainImages == null) || (MainImages.isEmpty())) {
                //无图像
                return "数据库中找不到已下载的影像记录！" + StudyInstanceUID;
            }
            for (int j = 0; j < MainImages.size(); j++) {
                Long FileSizeSum = 0L;
                int MaxFileCounts = 0;
                int FileCounts = MainImages.size();
                if (FileCounts > PostTencent.MAXIMAGECOUNTS) {
                    MaxFileCounts = PostTencent.MAXIMAGECOUNTS;
                } else {
                    MaxFileCounts = FileCounts;
                }

                JSONArray imageArray = new JSONArray();
                JSONObject singleImages = new JSONObject();
                //循环添加图像
                for (int i = 0; i < MaxFileCounts; i++) {
                    //String SeriesInstanceUID = MainImages.get(i).getStr("SeriesInstanceUID");
                    String SOPInstanceUID = MainImages.get(0).getStr("SOPInstanceUID");
                    String FilePath = MainImages.get(0).getStr("FilePath");
                    String FileName = MainImages.get(0).getStr("FileName");
                    FileName = FilePath + "\\" + FileName;

                    //判断图像是否超过20张或者大小不超过5M
                    Long FileSize = MainImages.get(0).getLong("FileSize");
                    FileSizeSum = FileSizeSum + FileSize;
                    if (FileSizeSum > PostTencent.MAXIMAGESIZE) {
                        break;
                    }

                    singleImages.put("imageId", SOPInstanceUID);
                    try {
                        singleImages.put("content", base64.encodeBase64File(FileName));//"c:\\aaa\\1.2.840.113681.2230565556.954.3591564731.78.1"));
                    } catch (Exception ex) {
                        PostTencent.ERRPOSTOPERFLAG = 1;
                        LogUtil.error("读Dicom文件使用Base64编码错误。位置postJsonDcm() 文件名SOPInstanceUID:" + SOPInstanceUID);
                        LogUtil.error(ex.toString());
                        java.util.logging.Logger.getLogger(PostDcm.class.getName()).log(Level.SEVERE, null, ex);
                        continue;
                    }
                    singleImages.put("url", "http://192.168.1.130/webreoprt/" + seriesNo);
                    //singleImages.put("descPosition", "0");
                    //singleImages.put("content", "很长");

                    imageArray.add(singleImages);
                    //移除已加入到JSON中的当前LIST中的图像
                    MainImages.remove(0);

                    //int JsonCounts = com.wzhq.model.MainImages.dao.findById(StudyInstanceUID, SeriesInstanceUID, SOPInstanceUID).getInt("JsonCounts");
                    //置已加入json"标记为真,操作本条记录次数加一
                    // com.wzhq.model.MainImages.dao.findById(StudyInstanceUID, SeriesInstanceUID, SOPInstanceUID).
                    //        set("JsonFlag", 1).set("JsonCounts", JsonCounts++).update();
                    //输出JSON格式的postImages数据
                    // System.out.println(postImages.toString());
                }
                postImages.put("images", imageArray);
                //待完善POST不成功异常处理
                int i = 0;
                do {
                    i++;
                    isSuccess = Post2Tencent(postImages, postUrl, interfaces);
                } while (!isSuccess || i > PostTencent.MAXREOPER);
                postImages.remove("images");
            }
            if (isSuccess) {
                //删除图像
            }
        } catch (JSONException e) {
            LogUtil.info("推送Post2Tencent出错: " + postImages);
        }
        //重新请求上传次数
        Record SyncAi = Db.findById("syncAIStatus", "StudyInstanceUID", StudyInstanceUID);
        int SyncAiCounts = SyncAi.getInt("SyncAiCounts") + 1;
        //解除防止线程读同一个病人,置图像已上传标志
        Record syncUNLock = Db.findById("syncAIStatus", "StudyInstanceUID", StudyInstanceUID).
                set("UsingFlag", "0").set("SyncAiFinshFlag", "1").set("SyncAiTime", df.format(day)).set("SyncAiCounts", SyncAiCounts);
        Db.update("syncAIStatus", "StudyInstanceUID", syncUNLock);
        return isSuccess ? "上传成功！" + StudyInstanceUID : "上传失败！" + StudyInstanceUID;
    }
    //向指定服务器发送JSON数据
    public boolean Post2Tencent(JSONObject jsonObj, String url, String interfaces) {
        int ERRPOSTOPERFLAG = 0;
        String StudyInstanceUID = jsonObj.getString("studyId");
        boolean isSuccess = false;
        HttpResponse response = null;
        HttpPost post = null;
        String strResult = "";
        JSONObject jsonResult = null; //返回的json对象
        int code = 9527;  //返回成功标记
        String message = "返回错误";
        JSONObject data = null; //返回的data json对象
        String Desc = "返回错误";
        int Result = 9527; //AI结果枚举
        int responseBackCode = 0;
        try {
            HostnameVerifier hostnameVerifier = org.apache.http.conn.ssl.SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER;
            DefaultHttpClient client = new DefaultHttpClient();
            SchemeRegistry registry = new SchemeRegistry();
            SSLSocketFactory socketFactory = SSLSocketFactory.getSocketFactory();
            socketFactory.setHostnameVerifier((X509HostnameVerifier) hostnameVerifier);
            registry.register(new Scheme("https", socketFactory, 443));
            SingleClientConnManager mgr = new SingleClientConnManager(client.getParams(), registry);
            DefaultHttpClient httpClient = new DefaultHttpClient(mgr, client.getParams());
            HttpsURLConnection.setDefaultHostnameVerifier(hostnameVerifier);
            //HttpClient httpClient = new DefaultHttpClient();
            // 设置超时时间
            httpClient.getParams().setParameter(CoreConnectionPNames.CONNECTION_TIMEOUT, 100000);
            httpClient.getParams().setParameter(CoreConnectionPNames.SO_TIMEOUT, 100000);

            post = new HttpPost(url);
            // 构造消息头
            String timeStamp = DicomUtil.getTimeStamp();
            String sessionId = DicomUtil.getUUID();
            post.setHeader("Content-type", "application/json; charset=utf-8");
            //post.setHeader("Connection", "Close");
            //post.setHeader("SessionId", sessionId);
            //post.setHeader("appid", appId);
            post.setHeader("god-portal-signature", DicomUtil.getSHA256Str(PostTencent.TOKEN, PostTencent.PARTNERID + timeStamp));
            post.setHeader("god-portal-timestamp", timeStamp);
            post.setHeader("god-portal-request-id", sessionId);

            // 构建消息实体
            StringEntity entity = new StringEntity(jsonObj.toString(), Charset.forName("UTF-8"));
            // entity.setContentEncoding("UTF-8");
            // 发送Json格式的数据请求
            entity.setContentType("application/json");
            post.setEntity(entity);
            LogUtil.info("向服务器提交请求中...................... ");
            response = httpClient.execute(post);
            LogUtil.info("已发送完影像................................. ");
            // 检验返回码
            responseBackCode = response.getStatusLine().getStatusCode();
            // Header[] header1 = response.getAllHeaders();
            // String strResult1 = EntityUtils.toString(response.getEntity());
            // LogUtil.info("\t" + strResult1);
            if (responseBackCode == HttpStatus.SC_OK) {
                try {
                    strResult = EntityUtils.toString(response.getEntity());
                } catch (IllegalStateException e) {
                    ERRPOSTOPERFLAG = 1;
                    LogUtil.error("转换提交JSON错误:" + StudyInstanceUID);
                    LogUtil.error(e.toString());
                    e.printStackTrace();
                } catch (IOException e) {
                    ERRPOSTOPERFLAG = 1;
                    LogUtil.error("转换解析提交JSON错误:" + StudyInstanceUID);
                    LogUtil.error(e.toString());
                    e.printStackTrace();
                }

                jsonResult = JSONObject.fromObject(strResult);
                try {
                    code = jsonResult.getInt("code");
                    message = jsonResult.getString("message");
                    // 判断data对象下的list是否存在
                    if (jsonResult.has("data")) {
                        data = jsonResult.getJSONObject("data");
                        Desc = data.getString("desc");
                        Result = data.getInt("result");
                    }
                } catch (JSONException e) {
                    ERRPOSTOPERFLAG = 1;
                    LogUtil.error("解析提交JSON错误:" + StudyInstanceUID);
                    LogUtil.error(e.toString());
                    e.printStackTrace();
                }
            } else {
                ERRPOSTOPERFLAG = 1;
                LogUtil.error("服务器响应错误，代码:" + responseBackCode);
            }

        } catch (ClientProtocolException e) {
            ERRPOSTOPERFLAG = 1;
            LogUtil.error("提交JSON错误ClientProtocolException:" + StudyInstanceUID);
            LogUtil.error(e.toString());
            e.printStackTrace();
        } catch (IOException e) {
            ERRPOSTOPERFLAG = 1;
            LogUtil.error("提交JSON错误IOException:" + StudyInstanceUID);
            LogUtil.error(e.toString());
            e.printStackTrace();
        } catch (Exception e) {
            ERRPOSTOPERFLAG = 1;
            LogUtil.error("提交JSON错误Exception:" + StudyInstanceUID);
            LogUtil.error(e.toString());
            e.printStackTrace();
        } finally {
            if (post != null) {
                try {
                    post.releaseConnection();
                    Thread.sleep(50);
                } catch (InterruptedException e) {
                    ERRPOSTOPERFLAG = 1;
                    e.printStackTrace();
                }
            }
        }
        try {
        //存入ReqResult表
        int ReqCounts = 1;
        Record ReqResult;
        ReqResult = Db.findById("ReqResult", "StudyInstanceUID,Interfaces", StudyInstanceUID, interfaces);
        if (ReqResult == null) {
            ReqResult = new Record().
                    set("StudyInstanceUID", StudyInstanceUID).set("Interfaces", interfaces).set("Code", code).set("Message", message).set("ReqCounts", ReqCounts)
                    .set("Data", jsonResult.toString()).set("ResponseBackCode", responseBackCode).set("ReceiveDate", JsfUtil.getDateTime());
            Db.save("ReqResult", "StudyInstanceUID,Interfaces", ReqResult);
        } else {
            ReqCounts = ReqResult.getInt("ReqCounts");
            ReqCounts++;
            ReqResult = Db.findById("ReqResult", "StudyInstanceUID,Interfaces", StudyInstanceUID, interfaces).
                    set("StudyInstanceUID", StudyInstanceUID).set("Interfaces", interfaces).set("Code", code).set("Message", message).set("ReqCounts", ReqCounts)
                    .set("Data", jsonResult.toString()).set("ResponseBackCode", responseBackCode).set("ReceiveDate", JsfUtil.getDateTime());
            Db.update("ReqResult", "StudyInstanceUID,Interfaces", ReqResult);
        }

        if (jsonResult.has("data")) {
            //存入Report表
            Record report;
            report = Db.findById("report", "StudyInstanceUID", StudyInstanceUID);
            int SyncCounts = 1;
            if (report == null) {
                report = new Record().
                        set("StudyInstanceUID", StudyInstanceUID).set("Desc", Desc).set("Result", Result)
                        .set("SyncCounts", SyncCounts++).set("ReportTime", JsfUtil.getDateTime());
                Db.save("report", "StudyInstanceUID", report);
            } else {
                SyncCounts = report.getInt("SyncCounts");
                SyncCounts++;
                report = Db.findById("report", "StudyInstanceUID", StudyInstanceUID).
                        set("StudyInstanceUID", StudyInstanceUID).set("Desc", Desc).set("Result", Result)
                        .set("SyncCounts", SyncCounts++).set("ReportTime", JsfUtil.getDateTime());
                Db.update("report", "StudyInstanceUID", report);
            }

            //写取报告标记
            Record syncReport = Db.findById("syncAIStatus", "StudyInstanceUID", StudyInstanceUID).set("ReportResult", Result).
                    set("ReportCounts", 1).set("ReportFlag", ERRPOSTOPERFLAG + 1).set("ReportTime", JsfUtil.getDateTime()).
                    set("ResponseBackCode", responseBackCode);
            Db.update("syncAIStatus", "StudyInstanceUID", syncReport);
            }
        } catch (Exception e) {
            ERRPOSTOPERFLAG = 1;
            LogUtil.error("提交JSON错误Exception:" + StudyInstanceUID);
            LogUtil.error(e.toString());
            e.printStackTrace();
        }
        return ERRPOSTOPERFLAG == 0;
    }


    public void main12(String[] args) throws IOException, Exception {
        //System.out.println(dateToStamp("2018-02-13 11:11:11"));
        //String url = "http://localhost:8080/HttpUpgrade";
        String url = "https://med-biz-pre.wecity.qq.com/api/aiyixue/uploadDicom/20000262";
        //String url = "https://med-biz-pre.wecity.qq.com/api/aiyixue/studyupload/20000262";

        String urlRes = "https://med-biz-pre.wecity.qq.com/api/aiyixue/dicomresult/20000262";

        //boolean a = httpPostWithJson(postJsonDcm(), PostTencent.URLDICOM);
        //httpPostWithJson(jSONGetReport("137034"), PostTencent.URLREPORT);
        //jSONObject();
    }

    @Override
    public void run() {
        String Message = "";
        System.out.println(jobName + "启动：" + Calendar.getInstance().get(Calendar.SECOND));
        Message = postJsonDcm(PostTencent.URLDICOM, PostTencent.POSTDICOM);
        //Thread.sleep(2000);
        System.out.println(jobName + " 退出，结果：" + Message + "|||" + Calendar.getInstance().get(Calendar.SECOND));
    }

}
